/**
 * Copyright (c) 2017, 西安星沙网络科技-版权所有
 *
 * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.gnu.org/licenses/lgpl-3.0.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.waleychain.exchange.consumer.controller.trade;

import java.math.BigDecimal;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;

import cn.waleychain.exchange.consumer.controller.BaseController;
import cn.waleychain.exchange.core.entity.PageInfo;
import cn.waleychain.exchange.core.logger.LoggerHelper;
import cn.waleychain.exchange.core.result.DefaultResult;
import cn.waleychain.exchange.core.result.IBaseResult;
import cn.waleychain.exchange.core.utils.BigDecimalUtils;
import cn.waleychain.exchange.feign.TradeServiceFeign;
import cn.waleychain.exchange.model.DealOrder;
import cn.waleychain.exchange.model.EntrustOrder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Api(description = "交易相关接口")
@RestController
@RequestMapping("api/v1/trade")
public class TradeController extends BaseController {

	private static final Logger mLog = LoggerFactory.getLogger(TradeController.class);
	
	@Autowired
	private TradeServiceFeign tradeFeign;
	
	@RequestMapping(value = "/fetchDealOrderPageList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	@ApiOperation(value = "分页获取完成订单列表", notes = "分页获取完成订单列表，URL: http://{ip}:{port}/{projectName}/api/v1/trade/fetchDealOrderPageList", httpMethod = "GET", response = DefaultResult.class)
	public IBaseResult fetchDealOrderPageList(
			@ApiParam(value = "交易市场ID", required = false) @RequestParam(required = false) Long marketId, 
			@ApiParam(value = "用户名称", required = false) @RequestParam(required = false) String userName,
			@ApiParam(value = "交易单号", required = false) @RequestParam(required = false) Long dealId,
			@ApiParam(value = "状态", required = false) @RequestParam(required = false) Integer status,
			@ApiParam(value = "类型（1 买 2 卖）", required = false) @RequestParam(required = false) Integer type,
			@ApiParam(value = "每次查询多少条数据", required = true) @RequestParam(required = true, defaultValue = "-1") Integer showCount, 
			@ApiParam(value = "当前查询页", required = true) @RequestParam(required = true, defaultValue = "1") Integer currentPage,  
			@RequestHeader String Authorization) throws Exception {

		try {

			PageInfo<DealOrder> page = tradeFeign.fetchDealOrderPageList(marketId, userName, dealId, status, type, showCount, currentPage);
			
			return DefaultResult.buildSuccessResult(page);
		} catch (Exception e) {
			LoggerHelper.printLogError(mLog, e, "分页获取完成订单列表");
		}

		return DefaultResult.buildFailedResult();
	}
	
	@RequestMapping(value = "/fetchEntrustOrderPageList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	@ApiOperation(value = "分页获取委托订单列表", notes = "分页获取委托订单列表，URL: http://{ip}:{port}/{projectName}/api/v1/trade/fetchEntrustOrderPageList", httpMethod = "GET", response = DefaultResult.class)
	public IBaseResult fetchEntrustOrderPageList(
			@ApiParam(value = "交易市场ID", required = false) @RequestParam(required = false) Long marketId,
			@ApiParam(value = "用户标识ID", required = false) @RequestParam(required = false) Long userId, 
			@ApiParam(value = "类型（1 买 2 卖）", required = false) @RequestParam(required = false) Integer type, 
			@ApiParam(value = "状态（1 未成交 2 已成交 3 已撤单）", required = false) @RequestParam(required = false) Integer status, 
			@ApiParam(value = "每次查询多少条数据", required = true) @RequestParam(required = true, defaultValue = "-1") Integer showCount, 
			@ApiParam(value = "当前查询页", required = true) @RequestParam(required = true, defaultValue = "1") Integer currentPage,
			@RequestHeader String Authorization) throws Exception {

		try {

			PageInfo<EntrustOrder> page = tradeFeign.fetchEntrustOrderPageList(marketId, userId, type, status, showCount, currentPage);
			
			return DefaultResult.buildSuccessResult(page);
		} catch (Exception e) {
			LoggerHelper.printLogError(mLog, e, "分页获取委托订单列表");
		}

		return DefaultResult.buildFailedResult();
	}
	
	@RequestMapping(value = "/createEntrustOrder", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	@ApiOperation(value = "创建委托订单", notes = "创建委托订单，URL: http://{ip}:{port}/{projectName}/api/v1/trade/createEntrustOrder", httpMethod = "POST", response = DefaultResult.class)
	public IBaseResult createEntrustOrder(
			@ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
			@ApiParam(value = "交易市场ID", required = true) @RequestParam Long marketId,
			@ApiParam(value = "委托价格", required = true) @RequestParam BigDecimal price, 
			@ApiParam(value = "委托数量", required = true) @RequestParam BigDecimal num,
			@ApiParam(value = "委托类型（1 买 2 卖）", required = true) @RequestParam Integer type, 
			@ApiParam(value = "交易密码", required = true) @RequestParam String payPassword,
			@RequestHeader String Authorization) throws Exception {

		try {

			boolean result = tradeFeign.createEntrustOrder(userId, marketId, price, num, type, payPassword);
			
			return DefaultResult.buildResult(result);
		} catch (Exception e) {
			LoggerHelper.printLogError(mLog, e, "创建委托订单");
		}

		return DefaultResult.buildFailedResult();
	}
	
	@RequestMapping(value = "/cancelEntrustOrder", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	@ApiOperation(value = "取消委托", notes = "取消委托，URL: http://{ip}:{port}/{projectName}/api/v1/trade/cancelEntrustOrder", httpMethod = "POST", response = DefaultResult.class)
	public IBaseResult cancelEntrustOrder(
			@ApiParam(value = "用户ID", required = true) @RequestParam Long userId,
			@ApiParam(value = "委托单标识ID", required = true) @RequestParam Long orderId,
			@RequestHeader String Authorization) throws Exception {

		try {

			boolean result = tradeFeign.cancelEntrustOrder(userId, orderId);
			
			return DefaultResult.buildResult(result);
		} catch (Exception e) {
			LoggerHelper.printLogError(mLog, e, "取消委托");
		}

		return DefaultResult.buildFailedResult();
	}
	
	@RequestMapping(value = "/fetchRecentlyEntrustList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	@ApiOperation(value = "获取最近的委托买单及委托卖单", notes = "获取最近的委托买单及委托卖单，URL: http://{ip}:{port}/{projectName}/api/v1/trade/fetchRecentlyEntrustList", httpMethod = "POST", response = DefaultResult.class)
    public IBaseResult fetchRecentlyEntrustList(
    		@ApiParam(value = "市场标识id", required = true) @RequestParam Long marketId,
			@ApiParam(value = "获取数据数量", required = true) @RequestParam int limit,
			@RequestHeader String Authorization) throws Exception {
		
		try {

			// 从内存中取
			List<EntrustOrder> buyList = tradeFeign.fetchRecentlyEntrustBuyList(marketId, limit);
			List<EntrustOrder> sellList = tradeFeign.fetchRecentlyEntrustSellList(marketId, limit);

			JSONObject json = new JSONObject();
			json.put("buyList", buyList);
			json.put("sellList", sellList);
			
			return DefaultResult.buildSuccessResult(json);
		} catch (Exception e) {
			LoggerHelper.printLogError(mLog, e, "获取最近的委托买单及委托卖单");
		}

		return DefaultResult.buildFailedResult();
    }
	
	@RequestMapping(value = "/fetchRecentlyDealList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	@ApiOperation(value = "获取最近成交的记录", notes = "获取最近成交的记录，URL: http://{ip}:{port}/{projectName}/api/v1/trade/fetchRecentlyDealList", httpMethod = "GET", response = DefaultResult.class)
    public IBaseResult fetchRecentlyDealList(
    		@ApiParam(value = "市场标识id", required = true) @RequestParam Long marketId,
			@ApiParam(value = "获取数据数量", required = true) @RequestParam int limit,
			@RequestHeader String Authorization) throws Exception {
		
		try {

			// 从内存中取
			List<DealOrder> list = tradeFeign.fetchRecentlyDealList(marketId, limit);
			
			return DefaultResult.buildSuccessResult(list);
		} catch (Exception e) {
			LoggerHelper.printLogError(mLog, e, "获取最近成交的记录");
		}

		return DefaultResult.buildFailedResult();
    }
	
    @RequestMapping(value = "/caculate", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	@ResponseBody
	@ApiOperation(value = "计算总额", notes = "计算总额，URL: http://{ip}:{port}/{projectName}/api/v1/trade/caculate", httpMethod = "GET", response = DefaultResult.class)
    public IBaseResult caculate(
    		@ApiParam(value = "价格", required = true)@RequestParam BigDecimal price, 
    		@ApiParam(value = "数量", required = true)@RequestParam BigDecimal num, 
    		@ApiParam(value = "费率", required = true)@RequestParam BigDecimal feeRate, 
    		@ApiParam(value = "保留小数位", required = true)@RequestParam int round) throws Exception { 
    	
    	try {
    		
    		BigDecimal total = price.multiply(num);
    		total = BigDecimalUtils.getRoundAmount(total.add(total.multiply(feeRate)), round);
    		
			return DefaultResult.buildSuccessResult(total.stripTrailingZeros().toPlainString());
		} catch (Exception e) {
			LoggerHelper.printLogError(mLog, e, "计算总额");
		}

		return DefaultResult.buildFailedResult();
    }
}
